package com.chen10.cattle.service.impl;

import com.chen10.cattle.common.constants.EmailConstants;
import com.chen10.cattle.common.constants.RedisKeyConstants;
import com.chen10.cattle.common.constants.UserConstants;
import com.chen10.cattle.common.enums.response.ErrorEnum;
import com.chen10.cattle.common.enums.response.SuccessMsgEnum;
import com.chen10.cattle.common.enums.user.UserStatusEnum;
import com.chen10.cattle.common.exception.BusinessException;
import com.chen10.cattle.common.protocal.ResponseResult;
import com.chen10.cattle.common.protocal.ResponseVO;
import com.chen10.cattle.common.utils.*;
import com.chen10.cattle.mapper.UserMapper;
import com.chen10.cattle.model.dto.LoginDTO;
import com.chen10.cattle.model.dto.RegisterDTO;
import com.chen10.cattle.model.pojo.User;
import com.chen10.cattle.model.vo.UserInfoVO;
import com.chen10.cattle.service.AuthService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class AuthServiceImpl implements AuthService {
    @Resource
    private UserMapper userMapper;

    @Resource
    private EmailUtil emailUtil;
    @Resource
    private RedisUtil redisUtil;

    /**
     * 用户登录
     * @param loginDTO email  password
     * @return
     */
    @Override
    public ResponseVO<Map<String,Object>> login(LoginDTO loginDTO) {
        //校验参数
        if(loginDTO == null){
            throw new BusinessException(ErrorEnum.PARAM_ERROR);
        }

        if(loginDTO.getEmail() == null || loginDTO.getPassword() == null){
            throw new BusinessException(ErrorEnum.PLEASE_ENTER_EMAIL_AND_PASSWORD);
        }

        if(!RegexUtils.isValidEmail(loginDTO.getEmail())){
            throw new BusinessException(ErrorEnum.EMAIL_INVALID);
        }

        //查询用户
        User user = userMapper.selectByEmail(loginDTO.getEmail());
        if(user == null){
            throw new BusinessException(ErrorEnum.USER_NOT_FOUND_EMAIL_UNREGISTER);
        }
        //比对密码
        String password_encoded =  DigestUtils.md5DigestAsHex(loginDTO.getPassword().getBytes());
        if(!password_encoded.equals(user.getPassword())){
            throw new BusinessException(ErrorEnum.PASSWORD_ERROR);
        }

        // 验证用户状态
        if (user.getStatus().equals(UserStatusEnum.DISABLED.getStatus())) {
            throw new BusinessException(ErrorEnum.USER_STATUS_DISABLED);
        }

        // 生成token
        String token = JwtUtil.getToken(user.getUserId());
        log.info("user login success, token:{}", token);

        //更新登录时间
        userMapper.updateLastLoginTime(user.getUserId(), LocalDateTime.now());

        // 返回登录信息
        UserInfoVO userInfoVO = new UserInfoVO();
        userInfoVO.setUserId(user.getUserId());
        userInfoVO.setUsername(user.getUsername());
        userInfoVO.setAvatarUrl(user.getAvatarUrl());

        Map<String,Object> map = new HashMap<>();
        map.put("token",token);
        map.put("userInfo",userInfoVO);

        //token存入redis
        redisUtil.setex(RedisKeyConstants.TOKEN_KEY_PREFIX + user.getUserId(),token, JwtUtil.TOKEN_TIME_OUT_SECOND, TimeUnit.SECONDS);

        return ResponseResult.success(SuccessMsgEnum.USER_LOGIN_SUCCESS.getMsg(),map);
    }

    /**
     * 注册
     * @param registerDTO
     * @return
     */
    @Override
    public void register(RegisterDTO registerDTO) {
        //校验参数
        if(registerDTO == null || registerDTO.getVerificationCode()==null){
            throw new BusinessException(ErrorEnum.PARAM_ERROR);
        }

        //邮箱校验参数
        if(!RegexUtils.isValidEmail(registerDTO.getEmail())) {
            throw new BusinessException(ErrorEnum.EMAIL_INVALID);
        }

        //判断邮箱是否被注册
        if(userMapper.selectByEmail(registerDTO.getEmail())!=null){
            throw new BusinessException(ErrorEnum.EMAIL_ALREADY_EXISTS);
        }

        //校验密码合法
        if(!RegexUtils.isValidPassword(registerDTO.getPassword())) {
            throw new BusinessException(ErrorEnum.PASSWORD_INVALID);
        }

        //校验邮箱验证码
        String key = EmailConstants.REGISTER_CODE_KEY_PREFIX + registerDTO.getEmail();
        if(!emailUtil.verifyCode(key,registerDTO.getVerificationCode())){
            throw new BusinessException(ErrorEnum.EMAIL_CODE_ERROR);
        }
        User user = new User();

        user.setEmail(registerDTO.getEmail());
        user.setUsername(GeneratorUtils.generateRandomUsername());
        user.setPassword(DigestUtils.md5DigestAsHex(registerDTO.getPassword().getBytes()));
        user.setAvatarUrl(UserConstants.AVATAR_URL_PREFIX+"/"+UserConstants.DEFAULT_AVATAR_NAME);
        user.setCreatedTime(new Date());
        user.setStatus(UserStatusEnum.ENABLED.getStatus());

        userMapper.insert(user);

    }


}
